import { JKManager } from "../JKManager"

type UserInfo = {
    userId: string,
}

type UserInfoCall = (userIds: string[]) => void

/**
 * 用户信息集合管理模块
 */
export class UserInfoManager {
    private _userInfos: UserInfo[]
    private _userInfosCalls: { [userId: string]: UserInfoCall[] }
    private _selfUserId: string

    /**
     * 初始化
     */
    init() {
        cc.log(`${cc.js.getClassName(this)} init`)

        this._userInfos = cc.js.createMap()
        this._userInfosCalls = cc.js.createMap()
    }

    //==============================================================================================================================
    //========================================================= 内部方法 ============================================================
    //==============================================================================================================================

    /**
     * 批量请求用户数据
     * @param userIds 用户Id集合
     */
    private _requestUserInfos(userIds: string[]) {
        cc.log(`${cc.js.getClassName(this)} _requestUserInfos userIds = `, userIds)
        
        userIds.length > 0 && JKManager.NetManager.sendSocketMsg(`AccountOfQueryUserInfosRequest`, {
            userIds: userIds,
        }, false)
    }

    //==============================================================================================================================
    //========================================================= 外部方法 ============================================================
    //==============================================================================================================================

    /**
     * 设置用户信息，如果有就信息，则合并属性
     * @param userInfos 用户信息
     */
    setUserInfos(userInfos: UserInfo[]) {
        cc.log(`${cc.js.getClassName(this)} setUserInfos userInfos = `, userInfos)

        let updateUserInfos: string[] = []
        if (userInfos.length > 0) {
            userInfos.forEach(userInfo => {
                // userInfo = {
                //     string userId = 1;
                // }
                let userId = userInfo.userId
                this._userInfos[userId] = this._userInfos[userId] || cc.js.createMap()
                cc.js.mixin(this._userInfos[userId], userInfo)
                updateUserInfos.push(this._userInfos[userId])
                if (userId === this._selfUserId) {
                    JKManager.GEventManager.emit(JKManager.Const.Common.EventType.SelfUserInfoUpdate, this._userInfos[userId])
                }
            })

            let key = JSON.stringify(userInfos.map(userInfo => userInfo.userId))
            if (this._userInfosCalls[key]) {
                this._userInfosCalls[key].forEach(call => {
                    call && call(updateUserInfos)
                })
                delete this._userInfosCalls[key]
            }
            JKManager.GEventManager.emit(JKManager.Const.Common.EventType.UserInfosUpdate, updateUserInfos)
        }
    }

    /**
     * 根据用户Id移除用户信息
     * @param userIds 用户Id
     */
    removeUserInfos(userIds: string[]) {
        cc.log(`${cc.js.getClassName(this)} removeUserInfos userIds`, userIds)

        userIds.forEach(userId => {
            if (userId !== this.getSelfUserId()) {
                delete this._userInfos[userId]
            }
        })
    }

    /**
     * 根据用户id获取用户信息，如果没有则请求，已有信息立即回调一次，没有的请求后回调一次
     * @param userIds 用户id
     * @param call 回调(Array userinfos用户信息)
     * @param forceRequest 强制请求最新数据，默认false
     */
    getUserInfos(userIds:string[], call: UserInfoCall, forceRequest = false) {
        cc.log(`${cc.js.getClassName(this)} getUserInfos userIds`, userIds)

        let userInfos = [],
            noUserIds = []
        userIds.forEach(userId => {
            if (!forceRequest && this._userInfos[userId]) {
                userInfos.push(this._userInfos[userId])
            } else {
                noUserIds.push(userId)
            }
        })
        if (userInfos.length > 0) {
            call && call(userInfos)
        }
        if (noUserIds.length > 0) {
            let key = JSON.stringify(noUserIds)
            this._userInfosCalls[key] = this._userInfosCalls[key] || []
            this._userInfosCalls[key].push(call)
            this._requestUserInfos(noUserIds)
        }
    }

    /**
     * 设置用户自己id
     * @param userId 用户id
     */
    setSelfUserId(userId: string) {
        cc.log(`${cc.js.getClassName(this)} setSelfUserId userId = ${userId}`)

        this._selfUserId = userId
    }

    /**
     * 获取用户自己的用户Id
     */
    getSelfUserId() {
        cc.log(`${cc.js.getClassName(this)} getSelfUserId`)
        return this._selfUserId
    }

    /**
     * 获取用户自己的用户信息
     */
    getSelfUserInfo() {
        cc.log(`${cc.js.getClassName(this)} getSelfUserInfo`)

        return this._userInfos[this._selfUserId]
    }
}